﻿using System;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing.Text;
using System.IO;
using System.Drawing;
using System.Text.RegularExpressions;

namespace Kaio.Core.Media
{
    public enum WatermarkPosition
    {

        TopLeft = 1,
        TopRight = 2,
        TopCenter = 3,
        BottomLeft = 4,
        BottomRight = 5,
        BottomCenter = 6,
        Center = 0

    }

   public class ImageHelper
    {

       public static bool IsGraphic(string FileName)
       {
           var _regex = new Regex(@"\.gif$|\.jpg$|\.jpeg$|\.png$|\.bmp$", RegexOptions.IgnoreCase);
           return _regex.IsMatch(FileName);
       }


       public static void ResizeImage(string source, string outputPath, Size _size)
       {
           ResizeImage(source, outputPath, _size.Width, _size.Height, null, 0, 0);

       }

       public static void ResizeImage(string source, string outputPath, int width, int height, string watermark, int watermarkPosition, double opacity)
       {


           try
           {
               using (Stream _fileStream = new FileStream(source, FileMode.Open))
               {
                   ResizeStream(_fileStream, outputPath, width, height, watermark, (WatermarkPosition) watermarkPosition,
                                opacity);
               }
           }
           catch (Exception ex)
           {



               throw new InvalidOperationException(ex.ToString());
           }

       }


       public static void ResizeStream(Stream source, string outputPath, int width, int height, string watermarkLogo, WatermarkPosition position, double opacity)
       {
           var _image = Image.FromStream(source);

           int _newWidth = width, _newHeight = height;

           // Only width defined
           if (width > 0 && height < 1)
           {
               if (_image.Width <= width)
               {
                   _newWidth = _image.Width;
                   _newHeight = _image.Height;
               }
               else
               {
                   float _dim = _image.Height / (float)_image.Width;
                   _newHeight = (int)(_dim * width);

               }

           }

           // Only height defined
           if (width < 1 && height > 0)
           {
               if (_image.Height <= height)
               {
                   _newWidth = _image.Width;
                   _newHeight = _image.Height;

               }
               else
               {
                   float dim = _image.Width / (float)_image.Height;
                   _newWidth = (int)(dim * height);

               }
           }

           var _bitmap = new Bitmap(_newWidth, _newHeight);

           var _graphic = Graphics.FromImage(_bitmap);
           _graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
           _graphic.SmoothingMode = SmoothingMode.HighQuality;
           _graphic.PixelOffsetMode = PixelOffsetMode.HighQuality;
           _graphic.CompositingQuality = CompositingQuality.HighQuality;
           _graphic.SmoothingMode = SmoothingMode.AntiAlias;
           _graphic.TextRenderingHint = TextRenderingHint.AntiAlias;
           var _imageRectangle = new Rectangle(0, 0, _newWidth, _newHeight);
           _graphic.DrawImage(_image, _imageRectangle);

           if (!String.IsNullOrEmpty(watermarkLogo))
           {
               Image _water = Image.FromFile(watermarkLogo);

               if (_water.Height < _newHeight && _water.Width < _newWidth)
               {
                   DrawImage(ref _bitmap, _water, position, opacity);
               }
               _water.Dispose();
           }

           string _path = outputPath.Substring(0, outputPath.LastIndexOf("\\"));

           if (!Directory.Exists(_path))
           {
               Directory.CreateDirectory(_path);
           }


           _bitmap.Save(outputPath, _image.RawFormat);
           _graphic.Dispose();
           _bitmap.Dispose();
           _image.Dispose();
       }


       public static void DrawImage(ref Bitmap _source, Image _waterMark, WatermarkPosition _position, double _transparent)
       {
           var _waterLogo = new Bitmap(_waterMark, _waterMark.Width, _waterMark.Height);


           Rectangle _rect;

           switch (_position)
           {
               //case WatermarkPosition.TopRight:
               case WatermarkPosition.TopRight:
                   _rect = new Rectangle(_source.Width - _waterLogo.Width, 0, _waterLogo.Width, _waterLogo.Height);
                   break;

               case WatermarkPosition.TopCenter:
                   _rect = new Rectangle((_source.Width - _waterLogo.Width) / 2, 0, _waterLogo.Width, _waterLogo.Height);
                   break;

               case WatermarkPosition.BottomLeft:
                   _rect = new Rectangle(0, _source.Height - _waterLogo.Height, _waterLogo.Width, _waterLogo.Height);
                   break;

               case WatermarkPosition.BottomRight:
                   _rect = new Rectangle(_source.Width - _waterLogo.Width, _source.Height - _waterLogo.Height, _waterLogo.Width, _waterLogo.Height);
                   break;

               case WatermarkPosition.BottomCenter:

                   _rect = new Rectangle((_source.Width - _waterLogo.Width) / 2, (_source.Height - _waterLogo.Height), _waterLogo.Width, _waterLogo.Height);
                   break;

               case WatermarkPosition.Center:
                   _rect = new Rectangle((_source.Width - _waterLogo.Width) / 2, (_source.Height - _waterLogo.Height) / 2, _waterLogo.Width, _waterLogo.Height);
                   break;

               default://TopLeft
                   _rect = new Rectangle(0, 0, _waterLogo.Width, _waterLogo.Height);
                   break;


           }


           Graphics _graphic = Graphics.FromImage(_source);

           //var ColorMatrix = new ColorMatrix();
           //ColorMatrix.Matrix33 = Convert.ToSingle(_transparent);
           //var _attributes = new ImageAttributes();
           //_attributes.SetColorMatrix(ColorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);

           _graphic.SmoothingMode = SmoothingMode.AntiAlias;

           _graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
           _graphic.SmoothingMode = SmoothingMode.HighQuality;
           _graphic.PixelOffsetMode = PixelOffsetMode.HighQuality;
           _graphic.CompositingQuality = CompositingQuality.HighQuality;
           _graphic.TextRenderingHint = TextRenderingHint.AntiAlias;

           //_graphic.DrawImage(_waterLogo, _rect, 0, 0, _waterLogo.Width, _waterLogo.Height, GraphicsUnit.Pixel, _attributes);
           _graphic.DrawImage(_waterLogo, _rect, 0, 0, _waterLogo.Width, _waterLogo.Height, GraphicsUnit.Pixel);

           _graphic.Dispose();



       }


       public static void AddWatermarkImage(Stream _fileSource, string _waterLogoFile, string _saveTo, WatermarkPosition _position, double _alpha)
       {

           Image _ImageSourceTemp = Image.FromStream(_fileSource);

           var _ImageSource = new Bitmap(_ImageSourceTemp, _ImageSourceTemp.Width, _ImageSourceTemp.Height);


           Graphics g = Graphics.FromImage(_ImageSource);

           var ColorMatrix = new ColorMatrix { Matrix33 = Convert.ToSingle(_alpha) };
           var ImgAttributes = new ImageAttributes();
           ImgAttributes.SetColorMatrix(ColorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);


           Image _waterLogoTemp = Image.FromFile(_waterLogoFile);

           var _waterLogo = new Bitmap(_waterLogoTemp, _waterLogoTemp.Width, _waterLogoTemp.Height);




           Rectangle _rect;

           switch (_position)
           {
               //case WatermarkPosition.TopRight:
               case WatermarkPosition.TopRight:
                   _rect = new Rectangle(_ImageSource.Width - _waterLogo.Width, 0, _waterLogo.Width, _waterLogo.Height);
                   break;

               case WatermarkPosition.TopCenter:
                   _rect = new Rectangle((_ImageSource.Width - _waterLogo.Width) / 2, 0, _waterLogo.Width, _waterLogo.Height);
                   break;

               case WatermarkPosition.BottomLeft:
                   _rect = new Rectangle(0, _ImageSource.Height - _waterLogo.Height, _waterLogo.Width, _waterLogo.Height);
                   break;

               case WatermarkPosition.BottomRight:
                   _rect = new Rectangle(_ImageSource.Width - _waterLogo.Width, _ImageSource.Height - _waterLogo.Height, _waterLogo.Width, _waterLogo.Height);
                   break;

               case WatermarkPosition.BottomCenter:

                   _rect = new Rectangle((_ImageSource.Width - _waterLogo.Width) / 2, (_ImageSource.Height - _waterLogo.Height), _waterLogo.Width, _waterLogo.Height);
                   break;

               case WatermarkPosition.Center:
                   _rect = new Rectangle((_ImageSource.Width - _waterLogo.Width) / 2, (_ImageSource.Height - _waterLogo.Height) / 2, _waterLogo.Width, _waterLogo.Height);
                   break;

               default://TopLeft
                   _rect = new Rectangle(0, 0, _waterLogo.Width, _waterLogo.Height);
                   break;


           }

           g.DrawImage(_waterLogo, _rect, 0, 0, _waterLogo.Width, _waterLogo.Height, GraphicsUnit.Pixel, ImgAttributes);

           g.SmoothingMode = SmoothingMode.HighQuality;
           g.InterpolationMode = InterpolationMode.HighQualityBicubic;

           g.Dispose();


           _ImageSource.Save(_saveTo, _ImageSource.RawFormat);

           _ImageSourceTemp.Dispose();
           _waterLogoTemp.Dispose();

           _waterLogo.Dispose();
           _ImageSource.Dispose();


       }


       public static string ImageToBase64(Image image, System.Drawing.Imaging.ImageFormat format)
       {
           using (var ms = new MemoryStream())
           {
               // Convert Image to byte[]
               image.Save(ms, format);
               byte[] imageBytes = ms.ToArray();

               // Convert byte[] to Base64 String
               string base64String = Convert.ToBase64String(imageBytes);
               return base64String;
           }
       }
       public static Image Base64ToImage(string base64String)
       {
           // Convert Base64 String to byte[]
           byte[] imageBytes = Convert.FromBase64String(base64String);
           var ms = new MemoryStream(imageBytes, 0,
             imageBytes.Length);

           // Convert byte[] to Image
           ms.Write(imageBytes, 0, imageBytes.Length);
           Image image = Image.FromStream(ms, true);
           return image;
       }

    }
}
